/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.data.orm.jpa;

import io.iec.edp.caf.data.multilang.CAFMultiLanguageColumn;
import lombok.var;
import org.hibernate.boot.model.naming.*;

/**
 * Hibernate隐式命名策略，尚未更改 {@link ImplicitNamingStrategy} that follows Spring recommended naming
 * conventions. Naming conventions implemented here are identical to
 * {@link ImplicitNamingStrategyJpaCompliantImpl} with the exception that join table names
 * are of the form
 * <code>{owning_physical_table_name}_{association_owning_property_name}</code>.
 *
 * @author Andy Wilkinson
 * @since 1.4.0
 */
public class CAFImplicitNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl {
    @Override
    public Identifier determineJoinTableName(ImplicitJoinTableNameSource source) {
        String name = source.getOwningPhysicalTableName() + "_"
                + source.getAssociationOwningAttributePath().getProperty();
        return toIdentifier(name, source.getBuildingContext());
    }

    @Override
    public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) {
        // JPA states we should use the following as default:
        //     "The property or field name"
        // aka:
        //     The unqualified attribute path.
        /**
         * 假如有实体：User{
         *     String id;
         *     String code;
         *     CAFMultiLanguageColumn name;
         * }
         * 嵌入类型：CAFMultiLanguageColumn{
         *     String cafMlcchs;
         *     String cafMlccht;
         *     String cafMlcen;
         * }
         * 则:
         *  FullPath是name.cafMlcen,name.cafMlcchs,name.cafMlccht
         *  getProperty()cafMlcchs,cafMlccht,cafMlcen
         *
         * 这里识别嵌入类型CAFMultiLanguageColumn的属性名
         * 如果是嵌入类型的属性名，证明当前字段是外部实体嵌入类型属性,则根据FullPath来做解析替换。
         * */
        var cafLanguagePropterty = source.getAttributePath().getProperty();
        if(isI18nColumn(cafLanguagePropterty)){
            //here like name.cafMlcchs
            var fullpath = source.getAttributePath().getFullPath();
            //here like _chs
            var languageSuffix = "_"+cafLanguagePropterty.replaceAll(CAFMultiLanguageColumn.fieldPrefix,"");
            //here like name.cafMlcen,the index will be 4
            var index = fullpath.indexOf(cafLanguagePropterty);
            //here like name_chs
            var columName = fullpath.substring(0,index-1)+languageSuffix;

            return toIdentifier( columName, source.getBuildingContext() );
        }else{
            return super.determineBasicColumnName(source);
        }

    }

    private boolean isI18nColumn(String property){
        boolean check = false;
        //这里忽略大小写判断
        for (var i : CAFMultiLanguageColumn.MlcColumn){
            if(i.equalsIgnoreCase(property)){
                check = true;
                break;
            }
        }

        return check;
    }
}